﻿AzureGames.AmazonsBoard = AzureGames.GameBoard.extend({
    init: function () {
        // call base method
        this._super();

        // 2 indicates an empty space
        this.board = EmptyBoard(10, 10, 2);

        this.board[0][3] = 0;
        this.board[0][6] = 0;
        this.board[3][0] = 0;
        this.board[3][9] = 0;

        this.board[9][3] = 1;
        this.board[9][6] = 1;
        this.board[6][0] = 1;
        this.board[6][9] = 1;

        this.PlayerIDs = new Array(1);
        this.Value = this.determinevalue();

        this.currentPhase = 0;
        this.currentPlayer = 0;

        this.state = 1;

        this.movedPiece = null;
    },
    /***** DETERMINEVALUE ********/
    determinevalue: function () {
        var whitevalue = 0;
        var blackvalue = 0;

        for (var r = 0; r < 10; r++) {
            for (var c = 0; c < 10; c++) {
                if (this.board[r][c] == 0) {
                    whitevalue += this.getValidMoves(r, c).length;
                }

                if (this.board[r][c] == 1) {
                    blackvalue += this.getValidMoves(r, c).length;
                }
            }
        }

        if (whitevalue == 0) {
            this.currentPhase = 3;
            this.state = 2;
        }

        if (blackvalue == 0) {
            this.currentPhase = 4;
            this.state = 2;
        }

        return whitevalue - blackvalue;
    },
    isFinalState: function () {
        return (this.currentPhase == 3 || this.currentPhase == 4);
    },

    /********** COPY ************/
    copyBoard: function () {
        var aCopy = new AzureGames.AmazonsBoard();

        for (var row = 0; row < 10; row++) {
            for (var col = 0; col < 10; col++) {
                aCopy.board[row][col] = this.board[row][col];
            }
        }
        return aCopy;
    },
    /***** GETVALIDMOVES ********/
    getValidMoves: function (row, col) {
        var moves = new Array();

        // forwards
        for (var c = col + 1; c < 10; c++)
            if (this.board[row][c] == 2)
                moves.push({ row: row, column: c });
            else
                break;

        // backwards
        for (var c = col - 1; c >= 0; c--)
            if (this.board[row][c] == 2)
                moves.push({ row: row, column: c });
            else
                break;

        // updwards
        for (var r = row + 1; r < 10; r++)
            if (this.board[r][col] == 2)
                moves.push({ row: r, column: col });
            else
                break;

        // downwards
        for (var r = row - 1; r >= 0; r--)
            if (this.board[r][col] == 2)
                moves.push({ row: r, column: col });
            else
                break;

        // diagonal forward up
        var r = row;
        for (var c = col + 1; c < 10; c++) {
            r += 1;
            if (r < 10) {
                if (this.board[r][c] == 2)
                    moves.push({ row: r, column: c });
                else {
                    c = 10;
                    break;
                }
            }
        }

        // diagonal forward down
        var r = row;
        for (var c = col + 1; c < 10; c++) {
            r -= 1;
            if (r >= 0) {
                if (this.board[r][c] == 2)
                    moves.push({ row: r, column: c });
                else {
                    c = 10;
                    break;
                }
            }
        }

        // diagonal backward up
        var r = row;
        for (var c = col - 1; c >= 0; c--) {
            r += 1;
            if (r < 10) {
                if (this.board[r][c] == 2)
                    moves.push({ row: r, column: c });
                else {
                    c = -1;
                    break;
                }
            }
        }

        // diagonal backward down
        var r = row;
        for (var c = col - 1; c >= 0; c--) {
            r -= 1;
            if (r >= 0) {
                if (this.board[r][c] == 2)
                    moves.push({ row: r, column: c });
                else {
                    c = -1;
                    break;
                }
            }
        }

        return moves;
    },
    /********** MOVEMODEL ***********/
    moveModel: function (locationFrom, locationTo, player) {
        var row = locationFrom.row;
        var col = locationFrom.column;

        this.board[row][col] = 2;

        row = locationTo.row;
        col = locationTo.column;

        this.movedPiece = new AzureGames.Location();
        this.movedPiece.row = row;
        this.movedPiece.column = col;

        this.board[row][col] = player;

        this.currentPhase = 1;

        this.Value = this.determinevalue();

        this.lastMove = new AzureGames.AmazonsMove();
        this.lastMove.model = locationFrom;
        this.lastMove.move = locationTo;
        this.lastMove.arrow = null;
        this.lastMove.value = this.Value;

    },
    /********** SHOOTARROW ***********/
    shootArrow: function (location) {
        var row = location.row;
        var col = location.column;

        this.board[row][col] = 3;
        this.movedPiece = null;

        this.currentPhase = 0;
        this.currentPlayer = this.currentPlayer == 0 ? 1 : 0;

        this.Value = this.determinevalue();

        if (this.lastMove == undefined)
            this.lastMove = new AzureGames.AmazonsMove();

        this.lastMove.arrow = location;
        this.lastMove.value = this.Value;

    },
    applyMove: function (move, player) {
        this.moveModel(move.model, move.move, player);
        this.shootArrow(move.arrow);
    },
    getMoves: function (player) {
        var ret = new Array();
        var board = this;

        for (var r = 0; r < 10; r++) {
            for (var c = 0; c < 10; c++) {

                if (this.board[r][c] == player) {
                    var model = new AzureGames.Location();
                    model.row = r;
                    model.column = c;

                    var moves = this.getValidMoves(model.row, model.column);

                    $.each(moves, function () {
                        var moveBoard = board.copyBoard();

                        var move = new AzureGames.Location();
                        move.row = this.row;
                        move.column = this.column;

                        moveBoard.moveModel(model, move);

                        var arrows = moveBoard.getValidMoves(move.row, move.column);
                        $.each(arrows, function () {
                            var arrowBoard = board.copyBoard();

                            var arrow = new AzureGames.Location();
                            arrow.row = this.row;
                            arrow.column = this.column;

                            arrowBoard.shootArrow(arrow);

                            var amazonsMove = new AzureGames.AmazonsMove();
                            amazonsMove.model = model;
                            amazonsMove.move = move;
                            amazonsMove.arrow = arrow;
                            amazonsMove.value = arrowBoard.value;
                            ret.push(amazonsMove);
                        });
                    });
                }
            }
        }

        return ret;
    },
    getModel: function () {
        // update the model with latest values and return model
        this.Model.Value = this.Value;
        this.Model.Properties[0] = $.toJSON(this.board).replace(/\"/g, "'");
        this.Model.Properties[1] = this.currentPhase;
        this.Model.Properties[2] = this.currentPlayer;
        this.Model.Properties[3] = $.toJSON(this.lastMove).replace(/\"/g, "'");
        this.Model.State = this.state;

        return this.Model;
    },
    updateModel: function (model) {
        // update the board with latest values received from the server
        this.Value = model.Value;
        this.LastUpdatedDate = model.LastUpdatedDate
        this.board = jQuery.parseJSON(model.Properties[0].replace(/'/g, "\""));
        this.currentPhase = model.Properties[1];
        this.currentPlayer = model.Properties[2];
        this.lastMove = jQuery.parseJSON(model.Properties[3].replace(/'/g, "\""));
        this.state = model.State;

        this.PlayerIDs = new Array(model.PlayerIDs.length);

        for (var playerID in model.PlayerIDs)
            this.PlayerIDs[playerID] = model.PlayerIDs[playerID];

        return this.Model;
    }
});

/***** JSON *********/
AzureGames.AmazonsBoard.SetModel = function (json) {
    var src = jQuery.parseJSON(json);
    var board = new AzureGames.AmazonsBoard();

    // used to post back
    board.Model = src;

    for (var prop in src)
        board[prop] = src[prop];

    // properties
    board.board = jQuery.parseJSON(src.Properties[0].replace(/'/g,"\""));
    board.currentPhase = src.Properties[1];
    board.currentPlayer = src.Properties[2];
    board.lastMove = jQuery.parseJSON(src.Properties[3].replace(/'/g, "\""));
    board.state = src.State;

    return board;
};